package leo.weixin.util;

import org.springframework.core.io.FileSystemResource;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;

import javax.net.ssl.HttpsURLConnection;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.Map;

/**
 * RestTemplate的简单封装
 */
public class RestTemplateUtil {
    private static final RestTemplate client = new RestTemplate();
    static {
        //解决了中文乱码
        client.getMessageConverters().set(1,new StringHttpMessageConverter(StandardCharsets.UTF_8));
    }

    /**
     * 无参get请求
     * @param url
     * @return 返回响应data的字符串格式
     */
    public static String get(String url){
        return client.getForObject(url, String.class);
    }

    /**
     * post请求
     * @param url
     * @param object 请求的对象
     * @return 返回响应data的字符串格式
     */
    public static String post(String url,Object object){
        return client.postForObject(url,object,String.class);
    }
    // todo 重载 filepath 和 multipartFile 对象
    public static String postFile(String url, File file, Map<String,Object> params){
        //设置头信息为二进制流
        HttpHeaders headers = new HttpHeaders();
        headers.set("Charset","utf8");
        headers.setAcceptCharset(Collections.singletonList(Charset.forName("UTF-8")));
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);
        headers.setConnection("Keep-Alive");
        headers.setContentDispositionFormData("media",file.getName());
        HttpEntity<FileSystemResource> httpEntity = new HttpEntity<>(new FileSystemResource(file), headers);
        ResponseEntity<String> entity = client.postForEntity(url, httpEntity, String.class, params);

        return entity.getBody();
    }

    /**
     * 向url上传一个文件 二进制流的方式
     * @param url
     * @param file
     * @return
     */
    public static String upload(String url,File file){
        try {
            URL urlObj = new URL(url);
            //强转为案例连接
            HttpsURLConnection conn = (HttpsURLConnection) urlObj.openConnection();
            //设置连接的信息
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            //设置请求头信息
            //conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Charset", "utf8");
            //数据的边界
            String boundary = "-----"+System.currentTimeMillis();
            conn.setRequestProperty("Content-Type", "multipart/form-data;boundary="+boundary);
            //获取输出流
            OutputStream out = conn.getOutputStream();
            //创建文件的输入流
            InputStream is = new FileInputStream(file);
            //第一部分：头部信息
            //准备头部信息
            StringBuilder sb = new StringBuilder();
            sb.append("--").append(boundary).append("\r\n")
                    .append("Content-Disposition:form-data;name=\"media\";filename=\""+file.getName()+"\"\r\n")
                    .append("Content-Type:application/octet-stream\r\n\r\n");
            out.write(sb.toString().getBytes());
            System.out.println(sb.toString());
            //第二部分：文件内容
            byte[] b = new byte[1024];
            int len;
            while((len=is.read(b))!=-1) {
                out.write(b, 0, len);
            }
            is.close();
            //第三部分：尾部信息
            String foot = "\r\n--"+boundary+"--\r\n";
            System.out.println(foot);
            out.write(foot.getBytes());
            out.flush();
            out.close();
            //读取数据
            InputStream is2 = conn.getInputStream();
            StringBuilder resp = new StringBuilder();
            while((len=is2.read(b))!=-1) {
                resp.append(new String(b,0,len));
            }
            return resp.toString();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
